local ROT = require 'rot'
local RNG = ROT.RNG

local Scene = require 'game.scene'

local SceneSpec = Scene:extend()

SceneSpec.name = 'Catacombs'

SceneSpec.innerWidth = 40
SceneSpec.innerHeight = 40
SceneSpec.maxDepth = 4

function SceneSpec:build(depth, x1, y1, x2, y2)

    self.ambientLight = { 160, 160, 200 }

    local floors = ROT.Type.Grid()
    local m

    if depth > 0 then
        self.innerWidth, self.innerHeight = 40 + depth * 5, 40 + depth * 5
        self.name = 'Catacombs ' .. tostring(depth)
        m = ROT.Map.Uniform:new(self.innerWidth, self.innerHeight, {
            roomDugPercentage = (1+depth)/8,
            roomWidth = { 4, depth == 1 and 4 or 6 },
            roomHeight = { 4, depth == 1 and 4 or 6 },
            snap = 5,
        })

        m:create(function (x, y, val)
            self.feature:setCell(x, y, val == 0 and 'floor' or nil)
        end)

        self:expand('wall')

    else
        local x, y = math.floor((x1 + x2) * 0.5), math.floor((y1 + y2) * 0.5)

        for _x = x1, x2 do for _y = y1, y2 do
            self.feature:setCell(_x, _y, 'tree')
        end end

        self.feature:setCell(x, y, 'grass')

        self.branches[#self.branches + 1] = { x = x, y = y, branch = 'catacombs' }
        self.feature:setCell(x, y, 'downstairs')
    end

    self:decimate('wall', 6, 1, 'grate')
    self:decimate('wall', 4, 1, 'grate')
    self:decimate('wall', 6, 1, 'dirt floor')

    self:with('grate'):near('grate', {3,4,5,6,7,8}):swap('wall'):apply()
    self:with('grate'):near('dirt floor', 0):swap('wall'):apply()
    self:with('dirt floor'):near('floor'):swap('wall'):apply()
    self:with('grate'):swap('dirt floor'):apply()

    if depth < 1 then
        return
    end

    -- [[
    local rooms = m:getRooms()
    for i = 1, #rooms do
        rooms[i]:getDoors(function(x, y)
            self.feature:setCell(x, y, 'door')
        end)
    end
    --]]

    self:with('dirt floor'):near('door'):swap('wall'):apply()
    self:with('dirt floor'):near('wall', 7):swap('torch'):apply()

    self:decimate('wall', 4, 1, 'grate')

    self:with('dirt floor'):near('torch'):swap('grate'):apply()

    self:with('dirt floor'):near('dirt floor', 2):swap('grate'):apply()

    self:with('wall'):near('wall', 0):swap('statue'):apply()

    self:with('dirt floor'):exec(function(self, x, y)
        -- if RNG:random() <= 0.25 then self:putItem(x, y, 'stick') end
        if RNG:random() <= 0.1 then
            local mob = self:spawn(x, y, 'mummy')
        elseif RNG:random() <= 0.1 then
            local mob = self:spawn(x, y, 'zombie')
        end
    end)

    -- self:decimate('wall', 6, 1, 'floor')
    -- self:decimate('wall', 6, 1, 'floor')

    local rooms = m:getRooms()
    local offset = depth == 1 and 1 or #self.previous.downstairs

    for i = 1, offset do
        local c = rooms[i]:getCenter()
        local x, y = c[1], c[2]
        self.upstairs[i] = { x = x, y = y }
        self.feature:setCell(x, y, 'upstairs')
        self.player.x, self.player.y = x, y
    end

    if depth < self.maxDepth then
        for i = offset + 1, offset + 3 do
            if not rooms[i] then break end
            local c = rooms[i]:getCenter()
            local x, y = c[1], c[2]
            self.downstairs[i - offset] = { x = x, y = y }
            self.feature:setCell(x, y, 'downstairs')
        end
    end

end

return SceneSpec
